#include "log.h"

void log_card(FILE *fp, card c) {
    char tmp[20];
    card_name(tmp, c);
    fprintf(fp, "%s", tmp);
}

void log_welcome(FILE *fp) {
    fprintf(fp, "Welcome to\n");
    fprintf(fp, "  ___                ____              _ \n");
    fprintf(fp, " / _ \\ _ __   ___   / ___|__ _ _ __ __| |\n");
    fprintf(fp, "| | | | '_ \\ / _ \\ | |   / _` | '__/ _` |\n");
    fprintf(fp, "| |_| | | | |  __/ | |__| (_| | | | (_| |\n");
    fprintf(fp, " \\___/|_| |_|\\___|  \\____\\__,_|_|  \\__,_|\n\n");
}

void log_args(FILE *fp, struct args args) {
    fprintf(fp, "---- Initial setup ----\n");
    fprintf(fp, "Number of rounds: %d\n", args.r);
    fprintf(fp, "Number of decks: %d\n", args.deck_count);
    fprintf(fp, "Number of players: %d\n\n", args.n);
}

void log_shuffle(FILE *fp, struct board *board) {
    fprintf(fp, "Shuffling cards...\n");
    fprintf(fp, "Shuffle result:\n");
    int card_displaied_count = 0;
    for (int i = board->stock_pile_count - 1; i >= 0; i--) {
        log_card(fp, board->stock_pile[i]);
        ++card_displaied_count;
        // Don't print "," after the last card
        if (card_displaied_count != board->stock_pile_count) {
            fprintf(fp, card_displaied_count % CARDS_IN_ONE_LINE == 0 ? ",\n" : ", ");
        }
    }
    fprintf(fp, "\n\n");
}

void log_init_result(FILE *fp, card c) {
    fprintf(fp, "Flipped: ");
    log_card(fp, c);
    fprintf(fp, "\n\n");
};

void log_game_header(FILE *fp) {
    fprintf(fp, "\n---- Game ----\n");
}

void log_game_summary(FILE *fp, struct player *players, struct board *board, struct args args) {
    fprintf(fp, "\n---- End of Round Stats ----\n");
    fprintf(fp, "Round %d ends.\n", board->round_count);
    fprintf(fp, "Round %d result:\n", board->round_count);
    for (int i = 0; i < args.n; i++)
        fprintf(fp, "Player %d: %d, total: %d\n", i, -players[i].card_count, players[i].score - players[i].card_count);
    fprintf(fp, "\n");
}

void log_turn_header(FILE *fp, struct player *player, struct board *board) {
    fprintf(fp, "---- Player %d's Turn ----\n", player->id);
    fprintf(fp, "Board top:\t");
    log_card(fp, board->top_card);
    fprintf(fp, "\n");
    if (board->force_draw) {
        fprintf(fp, "Note: You have to draw %d cards unless you use a special card.\n", board->force_draw);
    }
    log_player_cards(fp, player);
}

void log_player_cards(FILE *fp, struct player *player) {
    fprintf(fp, "Player %d cards: ", player->id);
    log_cards(fp, player->cards, player->card_count);
}

void log_draw_cards(FILE *fp, struct player *player, int cards_count) {
    fprintf(fp, "Player %d draws: ", player->id);
    log_cards(fp, &(player->cards[player->card_count - cards_count]), cards_count);
}

void log_board_topn(FILE *fp, struct board *board, int topn) {
    log_cards(fp, &(board->discard[board->discard_count - topn]), topn);
}

void log_player_played(FILE *fp, struct board *board, int cards_count, int player_id) {
    fprintf(fp, "Player %d plays: ", player_id);
    log_board_topn(fp, board, cards_count);
}

void log_cards(FILE *fp, card *cards, int cards_count) {
    int card_count[CARD_PER_DECK], card_displaied_count = 0;
    memset(card_count, 0, sizeof(card_count));
    for (int i = 0; i < cards_count; i++) card_count[cards[i].order]++;
    for (int i = 0; i < CARD_PER_DECK; i++) {
        for (int j = 0; j < card_count[i]; j++) {
            log_card(fp, (card){i, 0});
            ++card_displaied_count;
            // Don't print "," after the last card
            if (card_displaied_count != cards_count) {
                fprintf(fp, card_displaied_count % CARDS_IN_ONE_LINE == 0 ? ",\n" : ", ");
            }
        }
    }
    fprintf(fp, "\n");
}

void log_show_card(FILE *fp, int player_id, card c) {
    fprintf(fp, "Player %d drawed: ", player_id);
    log_card(fp, c);
    fprintf(fp, "\n");
}
